package com.czy;

import java.io.File;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class 搜索文件 {

    private enum FileType {
        DIRECTORY,
        FILE,
        ALL
    }

    private static final ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
    private static final SimpleLatch simpleLatch = new SimpleLatch(0);


    public static void main(String[] args) throws InterruptedException {
        Scanner sc = new Scanner(System.in);
        System.out.println("输入文件名称");
        String name = sc.nextLine();
        System.out.println("输入起始路径 ");
        String path = sc.nextLine();
        System.out.println("输入文件类型(1目录 2文件 3全部)");
        String type = sc.nextLine();
        searchFile(path, name, getType(type));
        simpleLatch.await();
        executorService.shutdownNow();
    }

    private static FileType getType(String type) {
        return switch (type) {
            case "1" -> FileType.DIRECTORY;
            case "2" -> FileType.FILE;
            case "3" -> FileType.ALL;
            default -> FileType.ALL;
        };
    }

    private static void searchFile(String path, String name, FileType fileType) {
        if (path == null || path.isEmpty()) {
            File[] files = File.listRoots();
            for (File file : files) {
                simpleLatch.countUp();
                executorService.submit(() -> {
                    try {
                        searchFile(file.getAbsolutePath(), name, fileType);
                    } catch (Exception e) {
                        simpleLatch.countDown();
                    }
                });
            }
        } else {
            File file = new File(path);
            if (!file.exists()) throw new RuntimeException("路径不存在");
            if (!file.isDirectory()) throw new RuntimeException("路径不是文件夹");
            File[] files = file.listFiles();
            for (File f : files) {
                if (f.isDirectory()) {
                    if ((fileType == FileType.DIRECTORY || fileType == FileType.ALL) && f.getName().contains(name)) {
                        String replace = f.getName().replace(name, "\33[32;4m" + name + "\33[0m");
                        System.out.format("Directory\t" + f.getParent() + (f.getParent().endsWith(File.separator) ? "" : File.separator) + replace + "\n");
                    }
                    simpleLatch.countUp();
                    executorService.submit(() -> {
                        try {
                            searchFile(f.getAbsolutePath(), name, fileType);
                        } catch (Exception e) {
                            simpleLatch.countDown();
                        }
                    });
                } else {
                    if ((fileType == FileType.FILE || fileType == FileType.ALL) && f.getName().contains(name)) {
                        String replace = f.getName().replace(name, "\33[32;4m" + name + "\33[0m");
                        System.out.format("File\t\t" + f.getParent() + (f.getParent().endsWith(File.separator) ? "" : File.separator) + replace + "\n");
                    }
                }
            }
            simpleLatch.countDown();
        }
    }


    /**
     * 简单Latch
     */
    public static class SimpleLatch {
        /**
         * 计数
         */
        private int count;

        /**
         * 构造函数
         *
         * @param count 计数
         */
        public SimpleLatch(int count) {
            this.count = count;
        }

        /**
         * 构造函数
         */
        public SimpleLatch() {
            this(1);
        }

        /**
         * 获取当前计数
         *
         * @return 当前计数
         */
        public synchronized int getCount() {
            return count;
        }

        /**
         * 等待
         *
         * @throws InterruptedException 线程中断异常
         */
        public synchronized void await() throws InterruptedException {
            while (count > 0) wait();
        }

        /**
         * 等待指定时间
         *
         * @param time     时间
         * @param timeUnit 时间单位
         * @return 是否等待成功
         * @throws InterruptedException 线程中断异常
         */
        public synchronized boolean await(Integer time, TimeUnit timeUnit) throws InterruptedException {
            long timeoutMillis = timeUnit.toMillis(time);
            long startTime = System.currentTimeMillis();
            while (count > 0) {
                long remainingTime = timeoutMillis - (System.currentTimeMillis() - startTime);
                if (remainingTime <= 0) return false;
                wait(remainingTime);
            }
            return true;
        }

        /**
         * 计数减一
         */
        public synchronized void countDown() {
            count--;
            notifyAll();
        }

        /**
         * 立即唤醒
         */
        public synchronized void awakenNow() {
            count = 0;
            notifyAll();
        }

        /**
         * 计数加一
         */
        public synchronized void countUp() {
            count++;
        }
    }

}
